<?php

namespace app\admin\controller;

use app\base\model\system\{SystemAdmin, SystemMenus, SystemRole, SystemAdminOperationLog};
use app\core\exception\BusinessException;
use app\core\exception\ErrorCode;
use app\core\util\JwtUtil;
use app\core\util\TokenUtil;
use think\Log;
use think\Request;

/**
 * 基类 所有控制器继承的类
 * Class Auth
 * @package app\admin\controller
 */
class adminAuthController extends AdminBaseController
{
    /**
     * 当前登陆管理员信息
     * @var
     */
    protected $adminInfo;

    /**
     * 当前登陆管理员ID
     * @var
     */
    protected $adminId;

    /**
     * 当前管理员权限
     * @var array
     */
    protected $auth = [];

    /**
     * 可以跳过权限验证的路由
     * @var array
     */
    protected $skipLogController = ['login'];

    /**
     * 需要记录管理员操作日志的action
     * @var array
     */
    protected $needRecordAdminOperationLogAction = [];

    protected function _initialize()
    {
        parent::_initialize();

        $token = TokenUtil::getRequestToken();

        if (empty($token)) {
            throw new BusinessException(ErrorCode::USER_LOGIN_EMPTY_TOKEN);
        }

        $payload = JwtUtil::verifyToken($token);

        if (!$payload) {
            throw new BusinessException(ErrorCode::USER_LOGIN_INVALID_TOKEN);
        }

        if (!TokenUtil::hasExitAdminLoginTokenCopy($token)) {
            throw new BusinessException(ErrorCode::USER_LOGIN_INVALID_TOKEN);
        }

        try {
            $adminInfo = SystemAdmin::getActiveAdminInfo($payload['admin_id']);
            $adminInfo['level'] === 0 || $this->checkAuth();//权限验证,权限不足抛出异常
            $this->adminInfo = $adminInfo;
            $this->adminId = $adminInfo['admin_id'];
            $this->auth = SystemAdmin::getActiveAdminAuth($adminInfo);
        } catch (\Exception $e) {
            throw new BusinessException($e->getCode(), $e->getMessage());
        }
    }


    protected function checkAuth($action = null, $controller = null, $module = null, array $route = [])
    {
        static $allAuth = null;
        if ($allAuth === null) {
            $allAuth = SystemRole::getAllAuth();
        }
        if ($module === null) {
            $module = $this->request->module();
        }
        if ($controller === null) {
            $controller = $this->request->controller();
        }
        if ($action === null) {
            $action = $this->request->action();
        }
        if (!count($route)) {
            $route = $this->request->route();
        }
        if (in_array(strtolower($controller), $this->skipLogController, true)) {
            return true;
        }
        $nowAuthName = SystemMenus::getAuthName($action, $controller, $module, $route);
        $baseNowAuthName = SystemMenus::getAuthName($action, $controller, $module, []);
        if ((in_array($nowAuthName, $allAuth) && !in_array($nowAuthName, $this->auth)) || (in_array($baseNowAuthName,
                    $allAuth) && !in_array($baseNowAuthName, $this->auth))) {
            throw new BusinessException(ErrorCode::AUTH_PERMISSION_DENIED);
        }

        return true;
    }


    /**
     * 记录管理员操作日志
     */
    public function __destruct()
    {
        $action = $this->request->action();

        if ($action && $this->needRecordAdminOperationLogAction && in_array($action,
                $this->needRecordAdminOperationLogAction) && $this->adminInfo) {
            SystemAdminOperationLog::addAdminOperationLog($this->adminInfo);
        } else {
            $userInfo = $this->adminInfo;
            $request = Request::instance();
            $data = [
                'admin_name' => $userInfo['admin_name'],
                'real_name' => $userInfo['real_name'],
                'url' => $request->domain() . $request->baseUrl(),
                'method' => $request->method(),
                'ip' => $request->ip(),
                'params' => $request->param(false),
                'time' => date('Y-m-d H:i:s')
            ];
            if (!empty($request->file())) {
                $file = $request->file();
                $data['file']['name'] = $file['file']->getInfo('name');
                $data['file']['size'] = $file['file']->getSize();
            }

            /*$logPath = LOG_PATH . 'operation' . DS;
            $logFileName = date('Ymd') . '.log';

            if (!file_exists($logPath)) {
                mkdir($logPath, 0755, true);
            }

            $fh = fopen($logPath . $logFileName, "a");
            fwrite($fh, json_encode($data) . "\n");
            fclose($fh);

            Log::info($data);*/

        }
    }
}